package ycl.message.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import io.github.biezhi.ome.OhMyEmail;
import io.github.biezhi.ome.SendMailException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import ycl.common.ApiResult;
import ycl.common.constants.RedisConstant;
import ycl.common.enums.ApiResultEnum;
import ycl.common.models.base.A;
import ycl.common.models.req.SmsReq;
import ycl.common.models.req.base.SendEmailReq;
import ycl.common.properties.EmailProperties;
import ycl.message.service.MessageService;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 消息逻辑层
 *
 * @author ycl
 * @date 2022/6/16 0016 11:32:29
 */
@Slf4j
@Service
public class MessageServiceImpl implements MessageService {

	@Resource
	private EmailProperties emailProperties;
	@Resource(name = "stringRedisTemplate1")
	private StringRedisTemplate stringRedisTemplate;

	@Override
	public ApiResult<A> sendEmail(SendEmailReq req) {
		return send(req.getTargetEmail(), req.getTitle(), req.getContent());
	}

	/**
	 * 发送邮件次数校验
	 *
	 * @param email
	 * @return
	 */
	private int sendCount(String email) {
		String key = RedisConstant.getEmailCountKey(email);
		String v = stringRedisTemplate.opsForValue().get(key);
		if (StrUtil.isBlank(v))
			return 0;
		return Integer.parseInt(v);
	}


	@Override
	@SuppressWarnings("all")
	public void deleteSendCount() {
		Set<String> keys = stringRedisTemplate.keys(RedisConstant.EMAIL + "*");
		if (CollUtil.isNotEmpty(keys)) {
			stringRedisTemplate.delete(keys);
		}
	}

	@Override
	public ApiResult<A> sendAuthCodeBindMobile(SmsReq req) {
		String authCode = RandomUtil.randomNumbers(6);
		String email = req.getEmail();
		ApiResult<A> result = send(email,
				"YCL SPRING CLOUD AUTH CODE",
				authCode+" , 有效时长: 5分钟, 请尽快操作");

		if (!result.isSuccess() || result.getCode() == ApiResultEnum.SC_INTERNAL_SERVER_ERROR.code)
			return result;
		stringRedisTemplate.opsForValue().set(
				RedisConstant.getEmailKey(email),
				authCode,
				5L,
				TimeUnit.MINUTES
		);
		return result;
	}


	private ApiResult<A> send(String email, String title, String content) {
		int count = sendCount(email);
		if (count++ >= 50)
			return ApiResult.fail("今日获取邮件已达上限");

		try {
			String username = emailProperties.getUsername();
			OhMyEmail.config(OhMyEmail.SMTP_QQ(false),
					username,
					emailProperties.getPassword());
			OhMyEmail.subject(title)
					.from(username)
					.to(email)
					.html(content)
					.send();
		} catch (SendMailException e) {
			log.error(e.getMessage(), e);
			return ApiResult.fail("发送失败");
		}
		stringRedisTemplate.opsForValue().set(
				RedisConstant.getEmailCountKey(email),
				count + "",
				24L,
				TimeUnit.HOURS
		);
		return ApiResult.success();
	}
}
